package com.ouc.dataMange.controller;

import java.util.List;
import javax.servlet.http.HttpServletResponse;

import com.ouc.common.config.OUCAjaxResult;
import com.ouc.common.ncRead.NcDao;
import com.ouc.common.utils.file.FileUtils;
import com.ouc.dataMange.domain.Upload;
import com.ouc.dataMange.service.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ouc.common.annotation.Log;
import com.ouc.common.core.controller.BaseController;
import com.ouc.common.core.domain.AjaxResult;
import com.ouc.common.enums.BusinessType;
import com.ouc.dataMange.domain.SysDataCheck;
import com.ouc.common.utils.poi.ExcelUtil;
import com.ouc.common.core.page.TableDataInfo;
import ucar.nc2.NetcdfFile;

/**
 * dataCheckController
 *
 * @author ouc
 * @date 2025-08-06
 */
@RestController
@RequestMapping("/dataMange/dataCheck")
public class SysDataCheckController extends BaseController {
  @Autowired
  private ISysDataCheckService sysDataCheckService;

  @Autowired
  private ISysDataSetService dataSetService;

  @Autowired
  private ISysMemoryDeviceService memoryDeviceService;

  @Autowired
  private CopernicusService copernicusService;

  @Autowired
  private AtmosphereService atmosphereService;

  @Autowired
  private NcDao ncDao;

  /**
   * 查询dataCheck列表
   */
//    @PreAuthorize("@ss.hasPermi('dataMange:dataCheck:list')")
  @GetMapping("/list")
  public TableDataInfo list(SysDataCheck sysDataCheck) {
    startPage();
    List<SysDataCheck> list = sysDataCheckService.selectSysDataCheckList(sysDataCheck);
    return getDataTable(list);
  }

  /**
   * 导出dataCheck列表
   */
  @PreAuthorize("@ss.hasPermi('dataMange:dataCheck:export')")
  @Log(title = "dataCheck", businessType = BusinessType.EXPORT)
  @PostMapping("/export")
  public void export(HttpServletResponse response, SysDataCheck sysDataCheck) {
    List<SysDataCheck> list = sysDataCheckService.selectSysDataCheckList(sysDataCheck);
    ExcelUtil<SysDataCheck> util = new ExcelUtil<SysDataCheck>(SysDataCheck.class);
    util.exportExcel(response, list, "dataCheck数据");
  }

  /**
   * 获取dataCheck详细信息
   */
  @PreAuthorize("@ss.hasPermi('dataMange:dataCheck:query')")
  @GetMapping(value = "/{id}")
  public AjaxResult getInfo(@PathVariable("id") Integer id) {
    return success(sysDataCheckService.selectSysDataCheckById(id));
  }

  /**
   * 新增dataCheck
   */
  @PreAuthorize("@ss.hasPermi('dataMange:dataCheck:add')")
  @Log(title = "dataCheck", businessType = BusinessType.INSERT)
  @PostMapping
  public AjaxResult add(@RequestBody SysDataCheck sysDataCheck) {
    return toAjax(sysDataCheckService.insertSysDataCheck(sysDataCheck));
  }

  /**
   * 修改dataCheck
   */
  @PreAuthorize("@ss.hasPermi('dataMange:dataCheck:edit')")
  @Log(title = "dataCheck", businessType = BusinessType.UPDATE)
  @PutMapping
  public AjaxResult edit(@RequestBody SysDataCheck sysDataCheck) {
    return toAjax(sysDataCheckService.updateSysDataCheck(sysDataCheck));
  }

  /**
   * 删除dataCheck
   */
  @PreAuthorize("@ss.hasPermi('dataMange:dataCheck:remove')")
  @Log(title = "dataCheck", businessType = BusinessType.DELETE)
  @DeleteMapping("/{ids}")
  public AjaxResult remove(@PathVariable Integer[] ids) {
    return toAjax(sysDataCheckService.deleteSysDataCheckByIds(ids));
  }

  /**
   * 对某一数据进行有效性检查
   */
  @ResponseBody
  @RequestMapping("/checkData")
  public OUCAjaxResult checkData(@RequestParam(value = "dataSetId") Integer dataSetId,
                                 @RequestParam(value = "fileId") Integer fileId,
                                 @RequestParam(value = "userId") Integer userId) {
    try {
      StringBuilder resultMessage = new StringBuilder();
      String filePath = "";
      String variableList = "";
      if (dataSetId == 5) {
        Upload upload = copernicusService.selectUploadByFileId(fileId);
        variableList = upload.getVariableList();
        filePath = memoryDeviceService.selectSysMemoryDeviceById(upload.getFileMemoryId()).getSysMemoryDevice() +
            dataSetService.selectSysDataSetById(upload.getFileDataSetId()).getDataSetDevice() + upload.getFilePath();
      } else if (dataSetId == 9) {
        Upload upload = atmosphereService.selectUploadByFileId(fileId);
        variableList = upload.getVariableList();
        filePath = memoryDeviceService.selectSysMemoryDeviceById(upload.getFileMemoryId()).getSysMemoryDevice() +
            dataSetService.selectSysDataSetById(upload.getFileDataSetId()).getDataSetDevice() + upload.getFilePath();
      } else {
        return OUCAjaxResult.error("输入参数错误，未查询到该数据集的信息");
      }
      resultMessage.append("检查文件：").append(FileUtils.getName(filePath)).append("。");
      if (filePath.endsWith(".nc")) {
        NetcdfFile ncFile = NetcdfFile.open(filePath);
        SysDataCheck dataCheckSelect = new SysDataCheck();
        dataCheckSelect.setUserId(userId);
        List<SysDataCheck> dataCheckList = sysDataCheckService.selectSysDataCheckList(dataCheckSelect);
        for (SysDataCheck dataCheck : dataCheckList) {
          if (!variableList.contains(dataCheck.getVariableName())) {
            resultMessage.append("已检查").append(dataCheck.getVariableName()).append("，未查到该变量。");
          } else {
            float[][] data2D = ncDao.getNcDataOfSlice(ncFile, dataCheck.getVariableName()).get(dataCheck.getVariableName()).getData2D();

            int flag = 0;
            float dataMin = dataCheck.getDataMin().floatValue();
            float dataMax = dataCheck.getDataMax().floatValue();
            for (int i = 0; i < data2D.length; i++) {
              for (int j = 0; j < data2D[0].length; j++) {
                if (!Float.isNaN(data2D[i][j]) &&( data2D[i][j] < dataMin || data2D[i][j] > dataMax) ){
                  flag = 1;
                }
              }
            }
            if (flag == 1) {
              resultMessage.append("已检查").append(dataCheck.getVariableName()).append("，该变量超过检查阈值。");
            } else {
              resultMessage.append("已检查").append(dataCheck.getVariableName()).append("，该变量通过检查。");
            }
          }
        }
      } else {
        return OUCAjaxResult.error("该文件格式无法检查");
      }

      return OUCAjaxResult.ok(resultMessage.toString());
    } catch (Exception e) {
      return OUCAjaxResult.error(e.toString());
    }
  }

}
